home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 The Geometry Center; University of Minnesota
- 1300 South Second Street; Minneapolis, MN 55454, USA;
-
- This file is part of geomview/OOGL. geomview/OOGL is free software;
- you can redistribute it and/or modify it only under the terms given in
- the file COPYING, which you should have received along with this file.
- This and other related software may be obtained via anonymous ftp from
- geom.umn.edu; email: software@geom.umn.edu. */
-
- /* Authors: Charlie Gunn, Pat Hanrahan, Stuart Levy, Tamara Munzner, Mark Phillips */
-
- #include "transform3.h"
-
-
- /*-----------------------------------------------------------------------
- * Function: Tm3Invert
- * Description: compute the inverse of a Transform
- * Args: m: the transform (INPUT)
- * mi: the inverse transform (OUTPUT)
- * Returns: nothing
- * Author: njt
- * Date: Sat Jul 18 12:04:19 CDT 1992
- */
- float
- Tm3Invert(m, mi)
- Transform3 m, mi;
- {
- register int i, j;
- register int k;
- float x;
- Transform3 t;
- float f;
- Tm3Copy(m, t);
- Tm3Copy(TM3_IDENTITY, mi);
-
- /* Components of unrolled inner loops: */
- #define SUB(v,k) v[j][k] -= f*v[i][k]
- #define SWAP(v,k) x = v[i][k], v[i][k] = v[largest][k], v[largest][k] = x
-
-
- for (i = 0; i < 4; i++) {
- int largest = i;
- float largesq = t[i][i]*t[i][i];
- for (j = i+1; j < 4; j++)
- if ((x = t[j][i]*t[j][i]) > largesq)
- largest = j, largesq = x;
-
- /* swap t[i][] with t[largest][] */
- SWAP(t,0); SWAP(t,1); SWAP(t,2); SWAP(t,3);
- SWAP(mi,0); SWAP(mi,1); SWAP(mi,2); SWAP(mi,3);
-
- for (j = i+1; j < 4; j++) {
- f = t[j][i] / t[i][i];
- /* subtract f*t[i][] from t[j][] */
- SUB(t,0); SUB(t,1); SUB(t,2); SUB(t,3);
- SUB(mi,0); SUB(mi,1); SUB(mi,2); SUB(mi,3);
- }
- }
- for (i = 0; i < 4; i++) {
- f = t[i][i];
- for (k = 0; k < 4; k++) {
- t[i][k] /= f;
- mi[i][k] /= f;
- }
- }
- for (i = 3; i >= 0; i--)
- for (j = i-1; j >= 0; j--) {
- f = t[j][i];
- SUB(t,0); SUB(t,1); SUB(t,2); SUB(t,3);
- SUB(mi,0); SUB(mi,1); SUB(mi,2); SUB(mi,3);
- }
-
- return 1;
- }
-